package com.frank.loadinglibrary.utils;

import com.frank.loadinglibrary.base.baseelement.IComponentCallback;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.render.PathEffect;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;

public class OverWatchViewItem {

    public static final int CORNER_PATH_EFFECT_SCALE = 8;

    public static final int ANIMATION_DURATION = 200;

    private Paint mPaint;

    private Path mPath;

    private float mScale = 0;

    private IComponentCallback callback;

    private Point mCenterPoint;

    private AnimatorValue mShowAnimation;
    private AnimatorValue mHideAnimation;
    private Color mColor;
    private int durtion;

    public OverWatchViewItem(IComponentCallback callback, Color color, Point centerPoint, int length, int dur) {
        if (dur > 0) {
            this.durtion = dur;
        } else {
            this.durtion = ANIMATION_DURATION;
        }
        this.callback = callback;
        mCenterPoint = centerPoint;
        mColor = color;
        mPaint = new Paint();
        mPaint.setColor(mColor);
        mPaint.setStrokeWidth(3);
        mPaint.setAlpha(0);


        PathEffect corEffect = new PathEffect(length / CORNER_PATH_EFFECT_SCALE);
        mPaint.setPathEffect(corEffect);

        Point[] points = getHexagonPoints(centerPoint, length);
        mPath = new Path();
        mPath.moveTo(points[1].getPointX(), points[1].getPointY());
        mPath.lineTo(points[2].getPointX(), points[2].getPointY());
        mPath.lineTo(points[3].getPointX(), points[3].getPointY());
        mPath.lineTo(points[4].getPointX(), points[4].getPointY());
        mPath.lineTo(points[5].getPointX(), points[5].getPointY());
        mPath.lineTo(points[6].getPointX(), points[6].getPointY());
        mPath.close();
        initAnimators();
    }

    public OverWatchViewItem(IComponentCallback callback, Color color, Point centerPoint, int length) {
        this(callback, color, centerPoint, length, ANIMATION_DURATION);
    }

    private void initAnimators() {
        mShowAnimation = new AnimatorValue();
        mShowAnimation.setDuration(durtion);
        mShowAnimation.setCurveType(Animator.CurveType.DECELERATE);
        mShowAnimation.setValueUpdateListener((animatorValue, v) -> {
            mScale = 0.5f + v / 2;
            mPaint.setAlpha((int) (v * 255));
            if (callback != null) {
                callback.reflushComponent();
            }
        });
        mHideAnimation = new AnimatorValue();
        mHideAnimation.setDuration(ANIMATION_DURATION);
        mHideAnimation.setCurveType(Animator.CurveType.DECELERATE);
        mHideAnimation.setValueUpdateListener((animatorValue, v) -> {
            mScale = 0.5f + (1f - v) / 2;
            mPaint.setAlpha((int) ((1f - v) * 255));
            if (callback != null) {
                callback.reflushComponent();
            }
        });
    }


    /**
     * @param centerPoint
     * @param height
     * @return seven points for Hexagon. 6(point)+1(center point)
     */
    public Point[] getHexagonPoints(Point centerPoint, int height) {

        Point[] points = new Point[7];
        float length = (float) (height / Math.tan(Math.PI / 3) * 2);

        points[0] = centerPoint;
        points[1] = new Point(centerPoint.getPointX(), centerPoint.getPointY() - length);
        points[2] = new Point(centerPoint.getPointX() + height, centerPoint.getPointY() - length / 2);
        points[3] = new Point(centerPoint.getPointX() + height, centerPoint.getPointY() + length / 2);
        points[4] = new Point(centerPoint.getPointX(), centerPoint.getPointY() + length);
        points[5] = new Point(centerPoint.getPointX() - height, centerPoint.getPointY() + length / 2);
        points[6] = new Point(centerPoint.getPointX() - height, centerPoint.getPointY() - length / 2);
        return points;

    }

    public void drawViewItem(Canvas canvas) {
        canvas.save();
        canvas.scale(mScale, mScale, mCenterPoint.getPointX(), mCenterPoint.getPointY());
        canvas.drawPath(mPath, mPaint);
        canvas.restore();

    }

    public AnimatorValue getShowAnimation() {
        return mShowAnimation;
    }


    public void reset() {
        mScale = 0;
        mPaint.setAlpha(0);
        if (callback != null) {
            callback.reflushComponent();
        }
    }

    public void setColor(Color color) {
        this.mColor = color;
        mPaint.setColor(color);
        if (callback != null) {
            callback.reflushComponent();
        }
    }

    public AnimatorValue getHideAnimation() {
        return mHideAnimation;
    }

}
